<template>
  <view class="modal" :class="{ 'alert-modal': !cancelText }" @touchmove.stop.prevent>
    <view class="modal-mask" v-if="visible" :style="zIndex ? { zIndex } : {}"></view>
    <view class="modal-wrapper" v-if="visible" :style="modalWrapperStyles">
      <view v-if="title || $slots.header" class="modal-header" :style="headerStyle">
        <text class="modal-title" v-if="title">{{ title }}</text>
        <slot name="header"></slot>
      </view>
      <view class="modal-body" :style="bodyStyle">
        <view class="modal-description" v-if="description">{{ description }}</view>
        <slot></slot>
      </view>
      <view v-if="cancelText || okText" class="modal-footer">
        <view
          class="modal-btn"
          :class="primaryCancel ? 'modal-confirm' : 'modal-cancel'"
          @click="cancel"
          v-if="cancelText"
          >{{ cancelText }}</view
        >
        <view class="modal-btn modal-confirm" :class="{ disabled: okDisabled }" @click="confirm" v-if="okText">
          <block v-if="!openType">{{ okText }}</block>
          <button v-else :openType="openType" class="wx-native-btn">{{ okText }}</button>
        </view>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { useEnvStore } from '@/store/env'
import type { CSSProperties } from 'vue'

const props = defineProps<{
  visible: boolean
  title?: string
  description?: string
  zIndex?: number
  okText?: string
  openType?: string
  okDisabled?: boolean
  cancelText?: string
  bottomOffset?: string
  primaryCancel?: boolean
  headerStyle?: CSSProperties
  modalStyle?: CSSProperties
  bodyStyle?: CSSProperties
  wrapperStyle?: CSSProperties
}>()
const emit = defineEmits<{
  (e: 'update:visible', visible: boolean): void
  (e: 'ok'): void
  (e: 'cancel'): void
  (e: 'close'): void
}>()

const envStore = useEnvStore()
const spaceHeight = computed(() => `calc(160rpx + ${envStore.titleBarHeight * 2}px)`)
const modalWrapperStyles = computed(() => {
  const styles: CSSProperties = {
    ...props.modalStyle,
  }
  if (typeof props.zIndex === 'number') {
    styles.zIndex = props.zIndex
  }
  if (typeof props.bottomOffset === 'string') {
    // styles.transform = `translate(-50%, calc(-50% - ${props.bottomOffset}))`
    styles.top = `calc(50% - ${props.bottomOffset})`
  }

  return {
    ...styles,
    ...props.wrapperStyle,
  }
})

function confirm() {
  emit('update:visible', false)
  emit('ok')
  emit('close')
}
function cancel() {
  emit('update:visible', false)
  emit('cancel')
  emit('close')
}
</script>

<style lang="less">
@modal-border-color: #e2e2e2;
.modal {
  &.alert-modal .modal-header {
    padding-bottom: 24rpx;
  }
  .modal-mask {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.4);
    z-index: 1009;
  }
  .modal-wrapper {
    position: fixed;
    width: calc(100vw - 128rpx);
    max-height: calc(100vh - v-bind(spaceHeight));
    top: 45%;
    left: 50%;
    display: flex;
    flex-direction: column;
    text-align: center;
    background: #ffffff;
    border-radius: 16rpx;
    transition: transform 0.2s ease-in-out;
    transform: translate(-50%, -50%);
    box-sizing: border-box;
    overflow: hidden;
    z-index: 1010;
  }
  .modal-header,
  .modal-footer {
    flex-shrink: 0;
    overflow: hidden;
  }
  .modal-header {
    padding: 48rpx 32rpx 16rpx;
    text-align: center;
    box-sizing: border-box;
    + .modal-body {
      padding-top: 0;
    }
  }
  .modal-title {
    font-weight: 600;
    font-size: 32rpx;
    color: var(--dark-color);
  }
  .modal-body {
    width: 100%;
    font-size: 32rpx;
    font-weight: 400;
    color: rgba(var(--dark-vector), 0.8);
    line-height: 48rpx;
    padding: 64rpx 32rpx 48rpx;
    box-sizing: border-box;
    flex: 1;
    overflow: auto;
  }
  .modal-footer {
    border-top: 2rpx solid @modal-border-color;
    height: 86rpx;
    display: flex;
    justify-content: space-between;
    align-items: center;
    overflow: hidden;
    .modal-btn + .modal-btn {
      position: relative;
      &::before {
        content: '';
        display: block;
        position: absolute;
        top: 0;
        left: 0;
        width: 2rpx;
        height: 100%;
        background-color: @modal-border-color;
      }
    }
  }
  .modal-btn {
    flex: 1;
    flex-shrink: 0;
    height: 88rpx;
    line-height: 88rpx;
    font-size: 32rpx;
    font-weight: 400;
    color: var(--dark-color);
    text-align: center;
    &.disabled {
      opacity: 0.6;
      pointer-events: none;
    }
  }
  .modal-confirm {
    color: var(--primary-color);
  }
}

.wx-native-btn {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  background-color: transparent;
  border: none;
  box-shadow: none;
  color: inherit;
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
}
.wx-native-btn::after {
  border: none;
  border-radius: 0;
}
.wx-native-btn[plain] {
  border: none;
}
</style>
